package com.example.aspect;

import com.example.framwork.result.ProjectResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author Sheeper
 * @date 2019/3/13.
 */
@Aspect
@Configuration
@Order(-1)
public class LogAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Pointcut("execution(public * com.example.controller..*.*(..))")
    public void log() {
    }

    @Around("log()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip = getIpAddress(request);
        MethodSignature signature = (MethodSignature) point.getSignature();
        //获取注解
        Method method = signature.getMethod();
        String opName = request.getRequestURI();
        if (method.getAnnotation(GetMapping.class) != null) {
            opName = opName + "/GetMapping";
        } else if (method.getAnnotation(PostMapping.class) != null) {
            opName = opName + "/PostMapping";
        } else if (method.getAnnotation(PatchMapping.class) != null) {
            opName = opName + "/PatchMapping";
        } else if (method.getAnnotation(DeleteMapping.class) != null) {
            opName = opName + "/DeleteMapping";
        }
        ProjectResult result = null;
        //执行方法
        Object object;
        try {
            object = point.proceed();
            if (object instanceof ProjectResult) {
                result = (ProjectResult) object;
            }
            if (result != null) {
                //翻译
                if (result.getMessage() != null) {
                    String lanmsg = "";
                    if (result.getVals() != null && result.getVals().size() > 0) {//有动态参数"
                        //lanmsg = (result.getMessage(), result.getVals());
                        lanmsg = (result.getMessage());
                    } else {
                        lanmsg = (result.getMessage());
                    }
                    if (!"".equals(lanmsg)) {
                        result.setMessage(lanmsg);
                    }
                }
            }
            //执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
          //  logger.info("ip " + ip + ", " + opName + "，请求成功，" + "请求耗时：" + time);
            return object;
        } catch (Exception e) {
            //执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
          //  logger.info("ip " + ip + ", " + opName + "，请求失败，" + "请求耗时：" + time);
            throw e;
        }
    }

    /**
     * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址;
     *
     * @param request
     * @return
     */
    private String getIpAddress(HttpServletRequest request) {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }
}
